import { createRouter, createWebHistory } from 'vue-router'
import { notification } from 'ant-design-vue'
import sysConfig from '@/config/index'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import systemRouter from './systemRouter'
import { afterEach, beforeEach } from './scrollBehavior'
import whiteListRouters from './whiteList'
import userRoutes from '@/config/route'
import tool from '@/utils/tool'
import { cloneDeep } from 'lodash-es'
import userCenterApi from '@/api/sys/userCenterApi'
import loginApi from '@/api/auth/loginApi'
import { globalStore, searchStore } from '@/store'

const modules = import.meta.glob('/src/views/**/**.vue')
// 进度条配置
NProgress.configure({ showSpinner: false, speed: 500 })

// 系统特殊路由
const routes_404 = [
	{
		path: '/:pathMatch(.*)*',
		hidden: true,
		component: () => import('@/layout/other/404.vue')
	}
]
// 系统路由
const routes = [...systemRouter, ...whiteListRouters, ...routes_404]
const router = createRouter({
	history: createWebHistory(),
	routes
})

// 设置标题
//document.title = sysBaseConfig.SYS_NAME

// 判断是否已加载过动态/静态路由
const isGetRouter = ref(false)

// 白名单校验
// 从路由中导出白名单
const exportWhiteListFromRouter = (router) => {
	// 定义一个空数组
	const res = []
	for (const item of router) res.push(item.path)
	return res
}
const whiteList = exportWhiteListFromRouter(whiteListRouters)

router.beforeEach(async (to, from, next) => {
	NProgress.start()
	const store = globalStore()
	const sysBaseConfig = tool.data.get('SYS_BASE_CONFIG') || store.sysBaseConfig
	// 动态标题
	document.title = to.meta.title ? `${to.meta.title} - ${sysBaseConfig.SYS_NAME}` : `${sysBaseConfig.SYS_NAME}`

	// 过滤白名单
	if (whiteList.includes(to.path)) {
		next()
		// NProgress.done()
		return false
	}

	const token = tool.data.get(sysConfig.ACCESS_TOEKN_KEY)
	if (to.path === '/login') {
		// 当用户输入了login路由，将其跳转首页即可
		if (token) {
			next({
				path: '/'
			})
			return false
		}
		// 删除路由(替换当前layout路由)
		router.addRoute(routes[0])
		isGetRouter.value = false
		next()
		return false
	} else {
		// 这里需要使用 localStorage 保存登录之前要访问的页面
		tool.data.set('LAST_VIEWS_PATH', to.fullPath)
	}
	if (!token) {
		next({
			path: '/login'
		})
		return false
	}
	// 整页路由处理
	if (to.meta.fullpage) {
		to.matched = [to.matched[to.matched.length - 1]]
	}
	// 加载动态/静态路由
	if (!isGetRouter.value) {
		let apiMenu = tool.data.get('MENU') || []
		if (from.path != '/login') {
			// 获取用户的菜单
			apiMenu = (await userCenterApi.userLoginMenu()) || []
			tool.data.set('MENU', apiMenu)
			const loginUser = await loginApi.getLoginUser()
			tool.data.set('USER_INFO', loginUser)
		}
		if (apiMenu.length === 0) {
			// 创建默认模块，显示默认菜单
			apiMenu[0] = cloneDeep(userRoutes.module[0])
			const userMenu = userRoutes.menu
			const childrenApiMenu = apiMenu[0].children
			apiMenu[0].children = [...userMenu, ...childrenApiMenu]
		}
		let menuRouter = filterAsyncRouter(apiMenu)
		menuRouter = flatAsyncRoutes(menuRouter)
		menuRouter.forEach((item) => {
			router.addRoute('layout', item)
		})
		const search_store = searchStore()
		search_store.init(menuRouter)
		isGetRouter.value = true
		next({ ...to, replace: true })
		return false
	}
	beforeEach(to, from)
	next()
})

router.afterEach((to, from) => {
	afterEach(to, from)
	NProgress.done()
})

router.onError((error) => {
	NProgress.done()
	notification.error({
		message: '路由错误',
		description: error.message
	})
})

// 入侵追加自定义方法、对象
router.getMenu = () => {
	let apiMenu = tool.data.get('MENU') || []
	// 增加固定路由
	if (apiMenu.length === 0) {
		// 创建默认模块，显示默认菜单
		apiMenu[0] = cloneDeep(userRoutes.module[0])
		const userMenu = userRoutes.menu
		const childrenApiMenu = apiMenu[0].children
		apiMenu[0].children = [...userMenu, ...childrenApiMenu]
	}
	return apiMenu
}

// 转换
// 过滤异步路由
const filterAsyncRouter = (routerMap) => {
	// 定义一个空数组，用于存储过滤后的路由
	const accessedRouters = []
	// 遍历路由数组
	routerMap.forEach((item) => {
		// 如果路由的meta属性不存在，则初始化为空对象
		item.meta = item.meta ? item.meta : {}
		// 处理外部链接特殊路由
		if (item.meta.type === 'iframe') {
			// 将路由的path属性赋值给meta属性的url属性
			item.meta.url = item.path
			// 将路由的name属性拼接在path属性前，形成新的path属性
			item.path = `/i/${item.name}`
		}
		// MAP转路由对象
		const route = {
			// 路由的path属性
			path: item.path,
			// 路由的name属性
			name: item.name,
			// 路由的meta属性
			meta: item.meta,
			// 路由的重定向属性
			redirect: item.redirect,
			// 如果路由的children属性存在且长度大于0，则递归调用filterAsyncRouter函数，否则赋值为null
			children: item.children.length > 0 ? filterAsyncRouter(item.children) : null,
			// 加载路由的组件
			component: loadComponent(item.component)
		}
		// 将路由对象添加到accessedRouters数组中
		accessedRouters.push(route)
	})
	// 返回过滤后的路由数组
	return accessedRouters
}
// 定义一个函数loadComponent，用于加载组件
const loadComponent = (component) => {
	// 如果组件存在
	if (component) {
		// 如果组件包含斜杠
		if (component.includes('/')) {
			// 返回模块中的组件
			return modules[`/src/views/${component}.vue`]
		}
		// 否则返回模块中的组件
		return modules[`/src/views/${component}/index.vue`]
	} else {
		// 如果组件不存在，则返回一个空组件
		return () => import(/* @vite-ignore */ `/src/layout/other/empty.vue`)
	}
}

// 路由扁平化
// 定义一个函数，用于将异步路由扁平化
const flatAsyncRoutes = (routes, breadcrumb = []) => {
	// 定义一个空数组，用于存储扁平化后的路由
	const res = []
	// 遍历路由
	routes.forEach((route) => {
		// 将当前路由复制一份
		const tmp = { ...route }
		// 如果当前路由有子路由
		if (tmp.children) {
			// 复制一份面包屑数组
			const childrenBreadcrumb = [...breadcrumb]
			// 将当前路由添加到面包屑数组中
			childrenBreadcrumb.push(route)
			// 复制一份当前路由
			const tmpRoute = { ...route }
			// 将面包屑数组添加到当前路由的meta中
			tmpRoute.meta.breadcrumb = childrenBreadcrumb
			// 删除当前路由的children属性
			delete tmpRoute.children
			// 将当前路由添加到结果数组中
			res.push(tmpRoute)
			// 递归调用flatAsyncRoutes函数，将子路由扁平化
			const childrenRoutes = flatAsyncRoutes(tmp.children, childrenBreadcrumb)
			// 将子路由添加到结果数组中
			childrenRoutes.map((item) => {
				res.push(item)
			})
		} else {
			// 复制一份面包屑数组
			const tmpBreadcrumb = [...breadcrumb]
			// 将当前路由添加到面包屑数组中
			tmpBreadcrumb.push(tmp)
			// 将面包屑数组添加到当前路由的meta中
			tmp.meta.breadcrumb = tmpBreadcrumb
			// 将当前路由添加到结果数组中
			res.push(tmp)
		}
	})
	// 返回结果数组
	return res
}

export default router
